<?php
defined('BASEPATH') or exit('No direct script access allowed');

class Word extends MY_Controller
{

    public function __construct()
    {
        parent::__construct();
        $this->load->model('WordDict');
        $this->load->model('TopicDetection');
        $this->load->model('TopicSlotInfo');
        $this->load->library('ChineseToPinyin');
    }

    /*
     * ------------------------------------
     * |
     * |页面加载部分
     * |
     * ------------------------------------
     */

    /* 词库默认页面 */
    public function getWordDefalut()
    {
        $this->load->view('home/wordOpen');
    }

    /* 词汇页卡 */
    public function index()
    {
        $data['permissionCode'] = implode(',',$this->session->permissionCode);
        $this->load->view('knowledgeManager/mainComment',$data);
    }

    /* 移动分类树 */
    public function catalogTree()
    {
        $this->load->view('knowledgeManager/catalogTree');
    }

    /* 新建词库条目 */
    public function createNewDialog()
    {
        $this->load->view('knowledgeManager/createNewDialog');
    }

    /* 编辑词库条目 */
    public function editNewDialog()
    {
        $this->load->view('knowledgeManager/editNewDialog');
    }

    /* 右键菜单 */
    public function rightMenu()
    {
        $this->load->view('knowledgeManager/rightMenu');
    }

    /*
     * ------------------------------------
     * |
     * |分类树和搜索部分
     * |1.分类树
     * |2.搜索
     * |
     * ------------------------------------
     */
    //判断权限
    private function treePermission($code){
        $permission = $_SESSION['permission'];
        return strstr($permission['topic_id'], $code);
    }

    /* 获取分类树 */
     public function getClassificationTree()
    {
        $id = $_REQUEST['id'];
        $res = array(
            'code' => 0,
            'msg' => ''
        );

        if ($id == 'ROOT' || empty($id)) {
            $fullType = 'ROOT';
        } else {
            $fullType = $this->getfullTypeById($id);
        }
        $condition = array(
            'full_type' => $fullType,
            'is_valid' => true
        );

        $tree = $this->WordDict->find($condition);

        if (empty($tree)) {
            $res['code'] = 2;
            $res['msg'] = '未查询到记录！';
            echo json_encode($res);
            return false;
        }

        $field = array(
            '_id',
            'word',
            'synonyms',
            'operator',
            'pubtime',
            'full_type'
        );
        $data = array();
        foreach ($tree as $v) {
            if($v['full_type'] == 'ROOT'&&!$this->treePermission($v['_id'])){
                continue;
            }
            foreach ($field as $v1) {
                $temp[$v1] = $v[$v1];
            }
            if ($v['is_path']) {
                $fullType = $v['full_type'] . '.' . $v['word_type'];
                $condition = array(
                    'full_type' => $fullType,
                    'is_valid' => true,
                    'is_path' => true
                );
                $count = $this->WordDict->getCount($condition);
                $temp['parentOfLeaf'] = $count ? false : true;
            }
            $data[] = $temp;
        }
        $res['code'] = 1;
        $res['msg'] = '查询成功！';
        $res['data'] = $data;
        echo json_encode($res);
    }
     public function getWord()
    {
        $showPage = 10;
        $id = $_REQUEST['id'];
        $pageSet = $_REQUEST['pageSet'];
        $pageNum = $_REQUEST['pageNum'];
        $skip = ($pageNum - 1) * $pageSet;
        $res = array(
            'code' => 0,
            'msg' => ''
        );

        if ($id == 'ROOT' || empty($id)) {
            $fullType = 'ROOT';
        } else {
            $fullType = $this->getfullTypeById($id);
        }
        $condition = array(
            'full_type' => $fullType,
            'is_valid' => true
        );
        $totalCount = $this->WordDict->getCount($condition);
        if ($totalCount % $pageSet == 0) {
            $totalPage = $totalCount / $pageSet;
        } else {
            $totalPage = intval($totalCount / $pageSet + 1);
        }

        $tree = $this->WordDict->find($condition, array(), $pageSet, $skip);

        if (empty($tree)) {
            $res['code'] = 2;
            $res['msg'] = '未查询到记录！';
            echo json_encode($res);
            return false;
        }

        $field = array(
            '_id',
            'word',
            'synonyms',
            'operator',
            'pubtime'
        );
        $data = array();
        foreach ($tree as $v) {
            foreach ($field as $v1) {
                $temp[$v1] = $v[$v1];
            }
            $data[] = $temp;
        }

        $pageInfo['totalCount'] = $totalCount;
        $pageInfo['pageNum'] = $pageNum;
        $pageInfo['pageSet'] = $pageSet;
        $pageInfo['showPage'] = $showPage;
        $pageInfo['totalPage'] = $totalPage;
        $pageInfo['id'] = $id;

        $res['code'] = 1;
        $res['msg'] = '查询成功！';
        $res['data'] = $data;
        $res['page'] = $pageInfo;
        echo json_encode($res);
    }

    private function getpermiCond(){
        $rootTopicId = $_SESSION['permission']['topic_id'];
        $rootTopicIdArr = explode(',', $rootTopicId);
        $condition = array();
        foreach ($rootTopicIdArr as $topicId){
            if(in_array($topicId, array('content','unit','word'))){
                continue;
            }
            $wordDict = $this->WordDict->findOne(array('_id'=>new MongoId($topicId)));
            if($wordDict){
                $fullType = $wordDict['full_type'].'.'.$wordDict['word_type'].'.';
                $fullType = preg_quote($fullType);
                $condition[] = new MongoRegex("/^$fullType.*/");

            }
        }
        return $condition;
    }
    
    /* 搜索词汇 */
    public function searchWord()
    {
        $showPage = 10;
        $id = $_REQUEST['id'];
        $keyword = trim($_REQUEST['keyword']);
        $pageSet = $_REQUEST['pageSet'];
        $pageNum = $_REQUEST['pageNum'];
        $beginTime = $_REQUEST['beginTime'];
        $endTime = $_REQUEST['endTime'];
        $username = $_REQUEST['username'];
        $skip = ($pageNum - 1) * $pageSet;
        $res = array(
            'code' => 0,
            'msg' => ''
        );
        
        if ($id == 'ROOT' || empty($id)) {
            $fullTypeCondi = $this->getpermiCond();
        } else {
            $fullType = $this->getfullTypeById($id);
            $fullTypeCondi = array(new MongoRegex("/^$fullType.*/"));
        }
        $keyword = preg_quote($keyword);
        $condition = array(
            'is_path' => false,
            'is_valid' => true,
//            'full_type' => new MongoRegex("/^$fullType.*/"),
            'full_type' => array('$in'=>$fullTypeCondi),
            '$or' => array(
                array(
                    'synonyms' => new MongoRegex("/.*$keyword.*/")
                ),
                array(
                    'word' => new MongoRegex("/.*$keyword.*/")
                )
            )
        );
        //根据输入时间段，拼接搜索条件
        if(!empty($beginTime) && !empty($endTime)){
            $condition['pubtime'] = array('$gte'=>$beginTime, '$lte'=>$endTime);
        }else if(empty($beginTime) && !empty($endTime)){
            $condition['pubtime'] = array('$lte'=>$endTime);
        }else if(!empty($beginTime) && empty($endTime)){
            $condition['pubtime'] = array('$gte'=>$beginTime);
        }
        //根据姓名输入，添加搜索条件
        if(!empty($username)){
            $condition['operator'] = $username;
        }
        $totalCount = $this->WordDict->getCount($condition);
        $result = $this->WordDict->find($condition, array(), $pageSet, $skip);
        if ($totalCount % $pageSet == 0) {
            $totalPage = $totalCount / $pageSet;
        } else {
            $totalPage = intval($totalCount / $pageSet + 1);
        }
        $pageInfo['totalCount'] = $totalCount;
        $pageInfo['pageNum'] = $pageNum;
        $pageInfo['pageSet'] = $pageSet;
        $pageInfo['showPage'] = $showPage;
        $pageInfo['totalPage'] = $totalPage;
        $pageInfo['id'] = $id;
        $pageInfo['keyword'] = $keyword;
        if ($result) {
            $res['code'] = 1;
            $res['msg'] = '查询成功！';
            $res['data'] = $result;
            $res['page'] = $pageInfo;
        } else {
            $res['code'] = 2;
            $res['msg'] = '没有查询到相关记录！';
        }
        echo json_encode($res);
    }

    /*
     * -----------------------------
     * |
     * | 词类操作部分
     * | 1.添加
     * | 2.编辑
     * | 3.删除
     * | 4.移动
     * |
     * -----------------------------
     */

    /* 添加词类 */
    public function addWord()
    {
        $id = $_REQUEST['id'];
        $word = trim($_REQUEST['word']);
        $synonym = trim($_REQUEST['synonym']);
        $operator = $_SESSION['user']['username'];
        $res = array(
            'code' => 0,
            'msg' => ''
        );
        $time = time();
        if (empty($word)) {
            $res['msg'] = '词类名不能为空！';
            echo json_encode($res);
            return false;
        }

        $parent = $this->isParentofLeaf($id);
        if (! $parent) {
            $res['code'] = 0;
            $res['msg'] = '当前分类不能添加!';
            echo json_encode($res);
            return false;
        }

        $synonym = "{$word},{$synonym}"; // 自动添加词类名
        $synonymArray = $this->parseSynonym($synonym); // 得到同义词数组
        $wordType = ChineseToPinyin::getCapital($word); // 得到word_type,利用中文转英文的类
        $full_type = $parent['full_type'] . '.' . $parent['word_type'];
        $condition = array(
            'full_type' => $full_type,
            'word' => $word
        );
        $value = array(
            'full_type' => $full_type,
            'full_word' => $parent['full_word'] . '.' . $parent['word'],
            'parent_word' => $parent['word'],
            'parent_type' => $parent['word_type'],
            'word' => $word,
            'word_type' => $wordType,
            'synonyms' => $synonymArray,
            'pubtime' => date('Y-m-d H:i:s', $time),
            'is_valid' => true,
            'is_path' => false,
            'operator' => $operator
        );
        $wordId = '';
        $result = $this->WordDict->find($condition);
        if ($result && $result[0]['is_valid']) {
            $res['msg'] = '该词汇已经存在！';
            echo json_encode($res);
            return false;
        } elseif ($result && ! $result[0]['is_valid']) {
            $wordId = $result['_id'];
            /* 更新操作 */
            $flag = $this->WordDict->update($condition, $value);
        } else {
            /* 插入操作 */
            $flag = $this->WordDict->insert($value);
            $wordId = (String)$value['_id'];
        }

        $info['id'] =  $wordId;
        $info['operator'] = $operator;
        $info['updateTime'] = date('Y-m-d H:i:s',  time());
        $res['data'] = $info;
        $res['code'] = 1;
        $res['msg'] = '添加成功！';
        echo json_encode($res);
    }

    /* 编辑词类 */
    public function editWord()
    {
        $id = $_REQUEST['id'];
        $word = trim($_REQUEST['word']);
        $synonym = trim($_REQUEST['synonym']);
        $operator = $_SESSION['user']['username'];
        $time = time();
        $res = array(
            'code' => 0,
            'msg' => ''
        );
        if (empty($word)) {
            $res['msg'] = '词类名不能为空！';
            echo json_encode($res);
            return false;
        }

        $synonym = "{$word},{$synonym}"; // 自动添加词类名
        $synonymArray = $this->parseSynonym($synonym); // 得到同义词数组
        $wordType = ChineseToPinyin::getCapital($word); // 得到word_type,利用中文转英文的类

        $condition = array(
            '_id' => new MongoId($id)
        );
        $value = array(
            'word' => $word,
            'word_type' => $wordType,
            'synonyms' => $synonymArray,
            'pubtime' => date('Y-m-d H:i:s', $time),
            'operator' => $operator
        );
        $result = $this->WordDict->update($condition, $value);
        $info['id'] =  $id;
        $info['operator'] = $operator;
        $info['updateTime'] = date('Y-m-d H:i:s',  time());
        $res['data'] = $info;
        $res['code'] = 1;
        $res['msg'] = '更新词类成功！';
        echo json_encode($res);
    }

    /* 删除词类 */
    public function deleteWord()
    {
        $id = $_REQUEST['id'];
        $operator = $_SESSION['user']['username'];
        $time = time();
        $res = array(
            'code' => 0,
            'msg' => ''
        );
        $condition = array(
            '_id' => new MongoId($id)
        );
        $value = array(
            'is_valid' => false,
            'operator' => $operator,
            'pubtime' => date('Y-m-d H:i:s', $time)
        );
        $result = $this->WordDict->update($condition, $value);
        $res['code'] = 1;
        $res['msg'] = '删除成功！';
        echo json_encode($res);
    }

    /* 移动词类 */
    public function moveWord()
    {
        $parentId = $_REQUEST['parentId'];
        $childId = $_REQUEST['childId'];
        $time = time();
        $operator = $_SESSION['user']['username'];
        $res = array(
            'code' => 0,
            'msg' => ''
        );
        if (empty($parentId) || empty($childId)) {
            $res['msg'] = '父节点id或者叶子结点id不能为空！';
            echo json_encode($res);
            return false;
        }
        $parent = $this->isParentofLeaf($parentId);
        if (! $parent) {
            $res['msg'] = '不能移动到当前分类';
            echo json_encode($res);
            return false;
        }

        /* 移动先判断是否有兄弟叶子，有直接移动，没有拷贝一份 */
        $condition = array(
            '_id' => new MongoId($childId)
        );
        $child = current($this->WordDict->find($condition));
        $condition = array(
            'full_type' => $child['full_type'],
            'is_valid' => true
        );
        $count = $this->WordDict->getCount($condition);

        $flag = false;
        if ($count == 1) {
            /* 复制一条到指定目录 */
            $value = array(
                'full_type' => $parent['full_type'] . '.' . $parent['word_type'],
                'full_word' => $parent['full_word'] . '.' . $parent['word'],
                'parent_word' => $parent['word'],
                'parent_type' => $parent['word_type'],
                'word' => $child['word'],
                'word_type' => $child['word_type'],
                'synonyms' => $child['synonyms'],
                'is_valid' => $child['is_valid'],
                'is_path' => $child['is_path'],
                'pubtime' => date('Y-m-d H:i:s', $time),
                'operator' => $operator
            );
            $flag = true;
            $result = $this->WordDict->insert($value);
        } else {
            /* 存在多条直接更新 */
            $condition = array(
                '_id' => new MongoId($childId)
            );
            $value = array(
                'full_type' => $parent['full_type'] . '.' . $parent['word_type'],
                'full_word' => $parent['full_word'] . '.' . $parent['word'],
                'parent_word' => $parent['word'],
                'parent_type' => $parent['word_type'],
                'pubtime' => date('Y-m-d H:i:s', $time),
                'operator' => $operator
            );
            $result = $this->WordDict->update($condition, $value);
        }

        $res['code'] = 1;
        $res['msg'] = $flag ? '当前分类只有一条词类，已复制一条到指定目录！' : '移动成功！';
        echo json_encode($res);
    }

    /*
     * -----------------------------
     * |
     * |分类操作部分
     * |1.添加
     * |2.修改
     * |3.删除
     * |
     * -----------------------------
     */

    /* 添加分类 */
    public function addTypeset()
    {
        $id = $_REQUEST['id'];
        $word = trim($_REQUEST['newTypeset']);
        $time = time();
        $operator = $_SESSION['user']['username'];
        $res = array(
            'code' => 0,
            'msg' => ''
        );
        if (empty($word)) {
            $res['msg'] = '分类名不能为空';
            echo json_encode($res);
            return false;
        }
        $numPattern = "/.*[0-9].*/";
        if(preg_match($numPattern, $word)){
            $res['msg'] = '分类名不能包含数字！';
            echo json_encode($res);
            return false;
        }


        $wordType = ChineseToPinyin::getCapital($word);

        /* 查看是在根节点下添加还是普通结点添加 */
        if ($id == 'tyROOT' || empty($id)) {
            $value = array(
                'full_type' => 'ROOT',
                'full_word' => 'ROOT',
                'parent_word' => 'ROOT',
                'parent_type' => 'ROOT'
            );

            $condition = array(
                'full_type' => 'ROOT',
                'word_type' => $wordType
            );
            $result = $this->WordDict->find($condition);
        } else {
            $condition = array(
                '_id' => new MongoId($id)
            );
            $parent = $this->WordDict->find($condition);
            $parent = $parent[0];
            $fullType = $parent['full_type'] . '.' . $parent['word_type'];
            $value = array(
                'full_type' => $fullType,
                'full_word' => $parent['full_word'] . '.' . $parent['word'],
                'parent_word' => $parent['word'],
                'parent_type' => $parent['word_type']
            );
            $condition = array(
                'full_type' => $fullType,
                'word_type' => $wordType
            );
            $result = $this->WordDict->find($condition);
        }

        /* 添加分类的时候判断是否可以添加，如果是叶子节点的父节点不能添加(ROOT结点不做判断) */
        if (isset($parent)) {
            $judge = $this->addTypesetJudge($parent);
            if ($judge === false) {
                /* 表明 是叶子节点的父节点 */
                $res['code'] = 2;
                $res['msg'] = '当前目录下不允许添加分类！';
                echo json_encode($res);
                return false;
            }
        }

        /* 查看新添加的分类是否存在 */
        if ($result) {
            /* 分类已经存在 */
            $Typeset = $result[0];
            if ($Typeset['is_valid']) {
                $res['code'] = 2;
                $res['msg'] = '该分类已经存在！';
                echo json_encode($res);
                return false;
            }

            /* 如果不可用表示已经被删除，需要将其以及子分类都显示出来 */
            $fullType = $Typeset['full_type'] . '.' . $Typeset['word_type'];
            $condition = array(
                '$or' => array(
                    array(
                        '_id' => new MongoId($Typeset['_id'])
                    ),
                    array(
                        // 'full_type' => new MongoRegex("/^$fullType.*/"),
                        'full_type' => new MongoRegex("/^($fullType$|$fullType\.)/")
                    )
                )
            );
            $updateValue = array(
                'is_valid' => true,
                'operator' => $operator,
                'pubtime' => date('Y-m-d H:i:s', $time)
            );
            $flag = $this->WordDict->update($condition, $updateValue, true);
            $data['id']= $Typeset['_id'];
        } else {
            /* 不存在则直接添加一条新的记录 */
            $value['word'] = $word;
            $value['word_type'] = $wordType;
            $value['synonyms'] = array();
            $value['pubtime'] = date('Y-m-d H:i:s', time());
            $value['is_valid'] = true;
            $value['is_path'] = true;
            $value['operator'] = $operator;
            $flag = $this->WordDict->insert($value);
            $data['id']=$value['_id']->{'$id'};
        }

        $res['code'] = 1;
        $res['msg'] = '添加分类成功！';
        $res['data'] = $data;
        echo json_encode($res);
    }

    /* 修改分类 */
    public function editTypeset()
    {
        $id = $_REQUEST['id'];
        $newWord = trim($_REQUEST['newWord']);
        $time = time();
        $operator = $_SESSION['user']['username'];
        $res = array(
            'code' => 0,
            'msg' => ''
        );
        if (empty($newWord) || empty($id)) {
            $res['msg'] = empty($newWord) ? '分类名不能为空！' : 'id不能为空！';
            echo json_encode($res);
            return false;
        }
        $numPattern = "/.*[0-9].*/";
        if(preg_match($numPattern, $newWord)){
            $res['msg'] = '分类名不能包含数字！';
            echo json_encode($res);
            return false;
        }


        $newWordType = ChineseToPinyin::getCapital($newWord);

        /* 修改当前分类名 */
        $condition = array(
            '_id' => new MongoId($id)
        );
        $oldTypeset = $this->WordDict->find($condition);
        $oldTypeset = $oldTypeset[0];
        $value = array(
            'word' => $newWord,
            'word_type' => $newWordType,
            'pubtime' => date('Y-m-d H:i:s', $time),
            'operator' => $operator
        );
        $result = $this->WordDict->update($condition, $value);
        if ($result === false) {
            $res['msg'] = '修改失败，当前分类名已经存在，请使用其他分类名！';
            echo json_encode($res);
            return false;
        }

        /* 修改其子分类 */
        $oldFullType = $oldTypeset['full_type'] . '.' . $oldTypeset['word_type'];
        $oldFullWord = $oldTypeset['full_word'] . '.' . $oldTypeset['word'];
        $newFullType = $oldTypeset['full_type'] . '.' . $newWordType;
        $newFullWord = $oldTypeset['full_word'] . '.' . $newWord;
        $condition = array(
            // 'full_type' => new MongoRegex("/^$oldFullType.*/")
            'full_type' => new MongoRegex("/^($oldFullType$|$oldFullType\.)/")
        );
        $child = $this->WordDict->find($condition);
        foreach ($child as $v) {
            $fullType = str_replace($oldFullType, $newFullType, $v['full_type']);
            $fullWord = str_replace($oldFullWord, $newFullWord, $v['full_word']);
            $value = array(
                'full_type' => $fullType,
                'full_word' => $fullWord,
                'operator' => $operator,
                'pubtime' => date('Y-m-d H:i:s', $time)
            );
            if ($v['full_type'] == $oldFullType) {
                $value['parent_type'] = $newWordType;
                $value['parent_word'] = $newWord;
            }
            $condition = array(
                '_id' => new MongoId($v['_id'])
            );
            $result = $this->WordDict->update($condition, $value);
        }

        /* 修改topic_detection和topic_slot_info中的关联信息 */
        $data = array(
            'oldFullType' => $oldFullType,
            'newFullType' => $newFullType
        );
        $result = $this->updateTopic($data);

        $res['code'] = 1;
        $res['msg'] = '修改成功';
        echo json_encode($res);
    }

    /* 删除分类 */
    public function deleteTypeset()
    {
        $id = $_REQUEST['id'];
        $time = time();
        $operator = $_SESSION['user']['username'];
        $res = array(
            'code' => 0,
            'msg' => ''
        );
        if (empty($id)) {
            $res['msg'] = 'id不能为空！';
            echo json_encode($res);
            return false;
        }
        $fullType = $this->getfullTypeById($id);
        $condition = array(
            '$or' => array(
                array(
                    '_id' => new MongoId($id)
                ),
                array(
                    // 'full_type' => new MongoRegex("/^$fullType.*/"),
                    'full_type' => new MongoRegex("/^($fullType$|$fullType\.)/")
                )
            )
        );
        $value = array(
            'is_valid' => false,
            'pubtime' => date('Y-m-d H:i:s', $time),
            'operator' => $operator
        );
        $result = $this->WordDict->update($condition, $value, true);

        $res['code'] = 1;
        $res['msg'] = '删除成功！';
        echo json_encode($res);
    }

    /*
     * --------------------------------
     * |
     * | 上面是控制器部分，属性为public
     * | 下面是一些公用的方法，属性为private
     * |
     * --------------------------------
     */

    /* 通过id获取fulltype */
    private function getfullTypeById($id)
    {
        $condition = array(
            '_id' => new MongoId($id)
        );
        $field = array(
            'full_type',
            'word_type'
        );
        $parent = $this->WordDict->find($condition, $field);
        $fullType = $parent[0]['full_type'] . '.' . $parent[0]['word_type'];
        return $fullType;
    }

    /* 判断该记录是否是叶子节点的父节点 */
    private function isParentofLeaf($id)
    {
        $condition = array(
            '_id' => new MongoId($id)
        );
        $parent = $this->WordDict->find($condition);
        $fullType = $parent[0]['full_type'] . '.' . $parent[0]['word_type'];

        $condition = array(
            'full_type' => $fullType,
            'is_valid' => true
        );
        $field = array();
        $child = $this->WordDict->find($condition, $field, 1);
        if ($child && $child[0]['is_path']) {
            return false;
        }
        return $parent[0];
    }

    /* 解析同义词 */
    private function parseSynonym($synonym)
    {
        $synonymDevideSymbols = $this->config->item('synonymDevideSymbols');
        $synonym = str_replace($synonymDevideSymbols, ',', $synonym);
        $synonymArray = explode(',', $synonym); // 得到同义词的数组
        foreach ($synonymArray as $k => $v) {
            /* 去掉空值 ，同时去掉同义词两边的空格 */
            $v = trim($v);
            if ($v != '') {
                $synonymArray[$k] = $v;
                continue;
            }
            unset($synonymArray[$k]);
        }
        $synonymArray = array_unique($synonymArray); // 去掉重复元素
        $synonymArray = array_values($synonymArray); // 对数组重排序
        return $synonymArray;
    }

    /* 修改分类名关联topic_detection(patterns)、topic_slot_info(slot_typ)操作 */
    private function updateTopic($data)
    {
        $mongoTime = new MongoDate();
        $operator = $_SESSION['user']['username'];
        $oldFullType = $data['oldFullType'];
        $newFullType = $data['newFullType'];
        /* 修改topic_detection(patterns) */
        $condition = array(
            'patterns' => new MongoRegex("/.*$oldFullType.*/")
        );
        $result = $this->TopicDetection->find($condition);
        $preg = "/([|{]){$oldFullType}([.|}])/";
        foreach ($result as $v) {
            $patterns = implode(',', $v['patterns']);
            $newPatterns = preg_replace($preg, '${1}' . $newFullType . '${2}', $patterns);
            $newPatterns = explode(',', $newPatterns);
            $condition = array(
                '_id' => new MongoId($v['_id'])
            );
            $value = array(
                'patterns' => $newPatterns,
                'operator' => $operator,
                'update_time' => $mongoTime
            );
            $flag = $this->TopicDetection->update($condition, $value);
        }

        /* 修改topic_slot_info(slot_type) */
        $preg = "/^($oldFullType$|$oldFullType\.)/";
        $condition = array(
            // 'slot_type' => new MongoRegex("/.*$oldFullType.*/"),
            'slot_type' => new MongoRegex($preg)
        );
        $result = $this->TopicSlotInfo->find($condition);
        $preg = "/{$oldFullType}([.,])/";
        foreach ($result as $v) {
            $slotType = implode(',', $v['slot_type']);
            $slotType .= ',';
            $newSlotType = preg_replace($preg, $newFullType . '${1}', $slotType);
            $newSlotType = rtrim($newSlotType, ',');
            $newSlotType = explode(',', $newSlotType);
            $condition = array(
                '_id' => new MongoId($v['_id'])
            );
            $value = array(
                'slot_type' => $newSlotType,
                'operator' => $operator,
                'update_time' => $mongoTime
            );
            $flag = $this->TopicSlotInfo->update($condition, $value);
        }
    }


    /* 判断目录下是否可以添加分类 */
    private function addTypesetJudge($parent)
    {
        $fullType = $parent['full_type'] . '.' . $parent['word_type'];
        $condition = array(
            'full_type' => $fullType,
            'is_valid' => true,
            'is_path' => false
        );
        $field = array();
        $child = $this->WordDict->find($condition, $field, 1);
        return $child ? false : true;
    }

    public function getClassificationTreeBySearch()
    {

        //获取查询参数数据
        $value = trim($_POST['value']);
        //$value = '股票';
        //判断是否为空
        if(empty($value)){
            echo json_encode(array());
            die;
        }
        //查询条件
        $condition = array(
            'word' => new MongoRegex("/.*{$value}.*/"),
            'is_path' => true,
            'is_valid' => true
        );
        //查询字段
        $showField = array('full_type','word_type','full_word', 'word');

        $target = $this->WordDict->find($condition, $showField);

        if (empty($target)) {
            echo json_encode(array('flag' => 'noData'));
            die;
        }

        /*获取父节点_id*/
        $fullTypeStr = '';
        foreach ($target as $treeVal) {
            $fullTypeStr = empty($fullTypeStr)?$treeVal['full_type'] : $fullTypeStr.".".$treeVal['full_type'];
        }
        $fullTypeArr = array_unique(explode('.', $fullTypeStr));
        sort($fullTypeArr);//key值默认连续 mongo不支持key不连续`$in`查询
        $nodes = $this->WordDict->find(array('word_type'=>array('$in'=>$fullTypeArr),'is_valid'=>true,'is_path'=>true),$showField);
        /*end*/

        /*判断是否为子节点*/
        foreach ($target as $v){
            $fullTypeCondition[] = $v['full_type'].'.'.$v['word_type'];
        }
        $getCLeaf = $this->WordDict->find(array('full_type'=>array('$in'=>$fullTypeCondition),'is_valid'=>true,'is_path'=>true),array('full_type'));
        foreach ($getCLeaf as $v){
            $getCLeafArr[$v['full_type']] = $v;
        }
        foreach($target as &$info){
            $info['is_leaf'] = isset($getCLeafArr[$info['full_type'].".".$info['word_type']])?true:false;
        }
        unset($info);
        /*end*/

        /*合并所有数据, 把当前数据路径补全*/
        $nodes = array_merge($nodes,$target);
        foreach($nodes as &$info){
            $info['word_type'] = $info['full_type'].".".$info['word_type'];//补全当前值 防止word_type重复
        }
        unset($info);

        /*父子节点分类*/
        $newNode = array();
        foreach($nodes as $k=>$info){
            $newNode[$info['full_type']][] = $info;
        }
        $this->nodes = $newNode;//写入全局变量

        /*获取完整的目录树结构*/
        $tree = $this->getChildrensData($this->nodes['ROOT']);

        /*获取所有一级节点其它部分数据 目的是为了: 添加is_leaf字段*/
        $root = $this->WordDict->find(array('full_type'=>'ROOT','is_valid'=>true,'is_path'=>true),$showField);
        $fullTypeCondition = array();
        foreach ($root as $v){
            $fullTypeCondition[] = $v['full_type'].'.'.$v['word_type'];
        }
        //对所有一级节点判断是否有子节点
        $getRootNode = $this->WordDict->find(array('full_type'=>array('$in'=>$fullTypeCondition),'is_valid'=>true,'is_path'=>true),array('full_type'));
        $isleafArr = array();
        foreach ($getRootNode as $v){
            $isleafArr[$v['full_type']] = $v;
        }
        unset($info);
        foreach($root as &$info){
            $info['is_leaf'] = isset($isleafArr[$info['full_type'].'.'.$info['word_type']])?true:false;
        }
        unset($info);
        /*end*/

        $tree = array_merge($tree,$root);//所有数据合并成整个大树 其中有重复分支

        //过滤重复分支
        $data = array();
        $dataKey = array();
        foreach($tree as $info){
            if(isset($dataKey[$info['_id']])){
                continue;
            }else{
                $dataKey[$info['_id']] = $info['_id'];
                if($info['full_type'] == 'ROOT'&&!$this->treePermission($info['_id'])){
                    continue;
                }
                $data[] = $info;
            }
        }

        echo json_encode($data);
    }

    /**
     * @param array $pnodes 当前父节点数组数据
     * @return mixed
     */
    public function getChildrensData($pnodes){
        foreach($pnodes as $key=>$info){
            $isChild = $this->getChildrensDataNode($info);
            if(!empty($isChild)){
                $pnodes[$key]['children'] = $this->getChildrensData($isChild);
            }
        }
        return $pnodes;
    }

    /**
     * @param array $pnode 对当前父节点数据局部处理 返回父节点数据
     * @return array
     */
    public function getChildrensDataNode($pnode){
        $arr = array();
        if(isset($this->nodes[$pnode['word_type']])){
            $arr = $this->nodes[$pnode['word_type']];
            foreach($arr as &$info){
                $info['parent_id'] = $pnode['_id'];
            }
            unset($info);
        }
        return $arr;
    }
}